package com.example.utils;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.example.common.MapConfig;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Component;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Map;

@Component
public class MapUtils {

    @Resource
    private MapConfig mapConfig;

    /**
     * 地址转换为经纬度
     *
     * @param address 地址
     * @return 经纬度信息的Map，包含经度(lng)和纬度(lat)
     * @throws IOException 当网络请求失败时抛出
     * @throws URISyntaxException 当URL格式错误时抛出
     */
    public Map<String, String> getLonAndLat(String address) throws IOException, URISyntaxException {
        String queryUrl = "https://restapi.amap.com/v3/geocode/geo?key=" + mapConfig.getKey() + "&address=" + address;
        String queryResult = getResponse(queryUrl);
        Map<String, String> map = new HashMap<>();
        
        JSONObject obj = JSONObject.parseObject(queryResult);
        if (obj != null && "1".equals(obj.getString("status"))) {
            JSONArray geocodes = obj.getJSONArray("geocodes");
            if (geocodes != null && !geocodes.isEmpty()) {
                JSONObject jobJSON = geocodes.getJSONObject(0);
                String location = jobJSON.getString("location");
                System.out.println("经纬度：" + location);
                String[] lonAndLat = location.split(",");
                if (lonAndLat.length == 2) {
                    map.put("lng", lonAndLat[0]);
                    map.put("lat", lonAndLat[1]);
                }
                return map;
            }
        }
        throw new RuntimeException("地址转换经纬度失败，错误码：" + (obj != null ? obj.getString("infocode") : "未知"));
    }

    /**
     * 将经纬度转换为地址
     *
     * @param getLng 经度
     * @param getLat 纬度
     * @return 地址名称
     * @throws IOException 当网络请求失败时抛出
     * @throws URISyntaxException 当URL格式错误时抛出
     */
    public String getAMapByLngAndLat(String getLng, String getLat) throws IOException, URISyntaxException {
        String url = "https://restapi.amap.com/v3/geocode/regeo?output=JSON&location=" + getLng + ","
                + getLat + "&key=" + mapConfig.getKey() + "&radius=0&extensions=base";
        
        String queryResult = getResponse(url);
        JSONObject obj = JSONObject.parseObject(queryResult);
        
        if (obj != null && "1".equals(obj.getString("status"))) {
            JSONObject regeocode = obj.getJSONObject("regeocode");
            if (regeocode != null && !regeocode.isEmpty()) {
                return regeocode.getString("formatted_address");
            }
            throw new RuntimeException("未找到相匹配的地址！");
        }
        throw new RuntimeException("请求错误！");
    }

    /**
     * 根据两个定位点的经纬度算出两点间的距离
     *
     * @param startLonLat 起始经纬度
     * @param endLonLat   结束经纬度（目标经纬度）
     * @return 两个定位点之间的距离（单位：米）
     * @throws IOException 当网络请求失败时抛出
     * @throws URISyntaxException 当URL格式错误时抛出
     */
    public double getDistance(String startLonLat, String endLonLat) throws IOException, URISyntaxException {
        String queryUrl = "https://restapi.amap.com/v3/distance?key=" + mapConfig.getKey() + "&origins=" + startLonLat + "&destination=" + endLonLat;
        String queryResult = getResponse(queryUrl);
        
        JSONObject obj = JSONObject.parseObject(queryResult);
        if (obj != null) {
            JSONArray results = obj.getJSONArray("results");
            if (results != null && !results.isEmpty()) {
                JSONObject result = results.getJSONObject(0);
                String distance = result.getString("distance");
                if (distance != null) {
                    return Double.parseDouble(distance);
                }
            }
        }
        throw new RuntimeException("无法获取距离信息");
    }

    /**
     * 发送HTTP请求并获取响应
     *
     * @param serverUrl 请求地址
     * @return 服务器响应内容
     * @throws IOException 当网络请求失败时抛出
     * @throws URISyntaxException 当URL格式错误时抛出
     */
    private String getResponse(String serverUrl) throws IOException, URISyntaxException {
        StringBuilder result = new StringBuilder();
        URL url = new URI(serverUrl).toURL();
        URLConnection conn = url.openConnection();
        
        try (BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()))) {
            String line;
            while ((line = in.readLine()) != null) {
                result.append(line);
            }
        }
        return result.toString();
    }
}
